<?php
/**
 * 支付宝支付
 */

namespace app\services;

use app\model\Bank;
use app\model\Change;
use app\model\User;
use think\facade\Db;
use utils\AliPay;

/**
 * Class AliPayServices
 * @package app\services
 * @method $this data($data)
 * @method $this type(int $type)
 * @method $this trade_type(string $trade_type)
 * @method $this userId(int $userId)
 */
class AliPayServices extends BasePayServices
{
    /**
     * 用户id
     * @var
     */
    protected $userId;

    /**
     * 数据体
     * @var
     */
    protected $data;

    /**
     * 支付类型 app jsapi
     * @var string
     */
    protected $trade_type;

    protected static $instance = null;

    public static function instance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new static();
        }
        return self::$instance;
    }

    public function __construct()
    {
        if (!$this->userId || !$this->data)
            return app('json')->json_error('下单失败');

    }

    /**
     * 统一下单
     * @return mixed
     */
    public function getUnifiedOrder()
    {
        Db::startTrans();
        try {
            $userId = $this->userId;
            list($body, $total_amount, $order_type, $remarks, $trade_type, $pay_way, $voucher_img) = $this->_payConf($this->userId, $this->data);
            $out_trade_no = rand(1000000000, 9999999999) . (string)date('ymdhis', time()) . (int)microtime(true); // 订单号
            /** @var AliPay $pay */
            $pay = app()->make(AliPay::class);
            if ($pay->pay_v == 1) {
                $rpm = $pay->unifiedOrder(compact('userId', 'body', 'out_trade_no', 'total_amount'));
            } else {
                $rpm = $pay->easyUnifiedOrder(compact('userId', 'body', 'out_trade_no', 'total_amount'));
            }
            if (!$rpm['flag']) {
                return app('json')->json_error($rpm['msg']);
            }

            $prepay_id = $pay::$mchid;
            $this->setPaymentOrder(compact('body', 'out_trade_no', 'total_amount', 'remarks', 'userId', 'trade_type', 'order_type', 'pay_way', 'voucher_img', 'prepay_id'), 1);
            Db::commit();
            return app('json')->json_success('支付宝统一下单成功', $rpm['data']);
        } catch (\Exception $exception) {
            Db::rollback();
            return app('json')->json_error('下单失败1' . $exception->getMessage());
        }
    }

    /**
     * 支付回调
     * @return $this
     */
    public function getNotifyInfo()
    {
        $pay = new AliPay();
        if ($pay->checkSign($this->data)) {
            if ($this->data['trade_status'] == 'TRADE_SUCCESS') {
                $this->notify_info = $this->data;
                $this->pay_status = true;
                $this->pay_way = 1;
            }
        }
        return $this;
    }

    /**
     * 提现
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function withdrawal()
    {
        $money = $this->data['money'];
        if (preg_match('/\.\d{3,}/', $money))
            return app('json')->json_error('提现金额不能超过两位小数');
        $user = User::lock(true)->where('id', $this->userId)->find();
        $bank = Db::name('bank')->where(['user_id' => $this->userId, 'type' => 1])->find();
        if ($user->status != 1)
            return app('json')->json_error('账号已被禁用');
        if ($user->is_real_name != 1)
            return app('json')->json_error('你还未实名认证');
        if (empty($bank))
            return app('json')->json_error('你还未绑定支付宝');
        if ($money <= 0)
            return app('json')->json_error('提现金额要大于0');
        if ($money > $user->money)
            return app('json')->json_error('余额不足');
        $pay_configs = get_config(2); // 获取支付设置
        if (empty($pay_configs)) {
            return app('json')->json_error('后台配置错误');
        }
        $service = $pay_configs['TRANSFERSERVICE'];
        $service_money = $money * $service / 100;
        $practical_money = $money - $service_money; // 最终金额
        if ($practical_money <= 0)
            return app('json')->json_error('提现金额必须大于0');
        if ($money < $pay_configs['AGENT_REFLECT_MONEY'])
            return app('json')->json_error('单笔提现金额小于' . $pay_configs['AGENT_REFLECT_MONEY'] . '元');
        if ($money > $pay_configs['TRANSFERMAX'])
            return app('json')->json_error('单笔提现金额大于' . $pay_configs['TRANSFERMAX'] . '元');

        $today = Db::name('withdrawal_log')
            ->field("
            CASE WHEN id>0 THEN count(id) ELSE 0 END count,
            CASE WHEN id>0 THEN sum(apply_money) ELSE 0 END money
            ")
            ->where('user_id', $this->userId)
            ->where('status', 1)
            ->whereTime('create_at', 'today')
            ->find();

        if ($today['count'] >= $pay_configs['TRANSFERMAXDAYNUM'])
            return app('json')->json_error('超出今日提现次数');
        if ($today['money'] + $money > $pay_configs['TRANSFERMAXTODAY'])
            return app('json')->json_error('超过今日最大转账金额' . $pay_configs['TRANSFERMAXTODAY'] . '元');

        $moth = Db::name('withdrawal_log')
            ->field("
            CASE WHEN id>0 THEN count(id) ELSE 0 END count,
            CASE WHEN id>0 THEN sum(apply_money) ELSE 0 END money
            ")
            ->where('user_id', $this->userId)
            ->where('status', 1)
            ->whereTime('create_at', 'moth')
            ->find();

        if ($moth['count'] >= $pay_configs['PERFORMANCE_UPPER'])
            return app('json')->json_error('超出本月提现次数');
        if ($moth['money'] + $money > $pay_configs['TRANSFERMAXMONTH'])
            return app('json')->json_error('超过本月最大转账金额' . $pay_configs['TRANSFERMAXMONTH'] . '元');

        $insert_log = [ // 提现流水
            'user_id' => $this->userId,
            'apply_money' => $money,
            'status' => 0,
            'zfb_number' => $bank['number'],
            'zfb_name' => $bank['name'],
            'channel' => 1,
            'service_money' => $service_money,
            'transfer_type' => $pay_configs['TRANSFERSTATUS'],
            'practical_money' => floor($practical_money * 100) / 100,
            'ip' => getClientIp(),
            'mchid' => Db::name('pay_config')->where('channel', 1)->value('mchid'), // 商户号
        ];

        Db::startTrans();
        try {
            Change::SetUserMoney($this->userId, $user->money, $money, 7, 2);
            $log_id = Db::name('withdrawal_log')->insertGetId($insert_log);
            $user->money -= $money;
            $user->save();
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return app('json')->json_error('提现失败2' . $e->getMessage());
        }
//        if ($pay_configs['TRANSFERSTATUS'] == 1) { // 自动转账
//            try {
//                /** @var AliPay $pay */
//                $pay = app()->make(AliPay::class, ['withdrawal']);
//                $rpm = $pay->withdrawal($insert_log);
//                if ($rpm['flag']) {
//                    Db::name('withdrawal_log')->where('id', $log_id)->update(['status' => 1, 'out_biz_no' => $rpm['data']['out_biz_no'], 'update_at' => date('Y-m-d H:i:s', time()), 'final_transfer_type' => 1]);
//                    return app('json')->json_success('提现成功2');
//                } else {
//                    Db::name('withdrawal_log')->where('id', $log_id)->update(['fail_log' => $rpm['msg'], 'status' => 2]);
//                    return app('json')->json_error('提现失败3');
//                }
//            } catch (\Exception $e) {
//                return app('json')->json_error('提现失败4' . $e->getMessage());
//            }
//        } else {
        return app('json')->json_success('提现成功3');
//        }
    }

    /**
     * 后台提现
     * @return mixed
     */
    public function adminWithdrawal()
    {
        $money = $this->data['apply_money']; // 申请的金额
        $practical_money = $this->data['practical_money']; // 最终金额
        if ($practical_money <= 0)
            return app('json')->json_error('提现金额必须大于0');
//        $user = Db::name('user')->field('money,status,is_auth')->where('id', $userId)->find();
//        if ($user['status'] != 1)
//            return app('json')->json_error('账号已被禁用');
//        if ($user['is_auth'] != 1)
//            return app('json')->json_error('你还未实名认证');
//        if ($money <= 0)
//            return app('json')->json_error('提现金额要大于0');
        $pay_configs = get_config(2); // 获取支付设置
//        if (empty($pay_configs))
//            return app('json')->json_error('后台配置错误');
//        if ($money < $pay_configs['AGENT_REFLECT_MONEY'])
//            return app('json')->json_error('单笔提现金额小于' . $pay_configs['AGENT_REFLECT_MONEY'] . '元');
//        if ($money > $pay_configs['TRANSFERMAX'])
//            return app('json')->json_error('单笔提现金额大于' . $pay_configs['AGENT_REFLECT_MONEY'] . '元');
//        $today = Db::name('withdrawal_log')
//            ->field("
//            CASE WHEN id>0 THEN count(id) ELSE 0 END count,
//            CASE WHEN id>0 THEN sum(apply_money) ELSE 0 END money
//            ")
//            ->where('uid', $userId)
//            ->where('status', 1)
//            ->whereTime('create_at', 'today')
//            ->find();
//        if ($today['count'] >= $pay_configs['TRANSFERMAXDAYNUM'])
//            return app('json')->json_error('超出今日提现次数');
//        if ($today['money'] + $money > $pay_configs['TRANSFERMAXTODAY'])
//            return app('json')->json_error('超过今日最大转账金额' . $pay_configs['TRANSFERMAXTODAY'] . '元');
//        $moth = Db::name('withdrawal_log')
//            ->field("
//            CASE WHEN id>0 THEN count(id) ELSE 0 END count,
//            CASE WHEN id>0 THEN sum(apply_money) ELSE 0 END money
//            ")
//            ->where('uid', $userId)
//            ->where('status', 1)
//            ->whereTime('create_at', 'moth')
//            ->find();
//        if ($moth['count'] >= $pay_configs['PERFORMANCE_UPPER'])
//            return app('json')->json_error('超出本月提现次数');
//        if ($moth['money'] + $money > $pay_configs['TRANSFERMAXMONTH'])
//            return app('json')->json_error('超过本月最大转账金额' . $pay_configs['TRANSFERMAXMONTH'] . '元');
        try {
            /** @var AliPay $pay */
            $pay = app()->make(AliPay::class, ['withdrawal']);
            $rpm = $pay->withdrawal($this->data);
            if ($rpm['flag']) {
                Db::name('withdrawal_log')->where('id', $this->data['id'])->update(['status' => 1, 'out_biz_no' => $rpm['data']['out_biz_no'], 'update_at' => date('Y-m-d H:i:s', time()), 'final_transfer_type' => $pay_configs['TRANSFERSTATUS']]);
                return app('json')->json_success('提现成功');
            } else {
                Db::name('withdrawal_log')->where('id', $this->data['id'])->update(['fail_log' => $rpm['msg'], 'status' => 2]);
                return app('json')->json_error('提现失败');
            }
        } catch (\Exception $e) {
            return app('json')->json_error('提现失败');
        }
    }

    /**
     * 后台扶持提现
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function adminSupportWithdrawal()
    {

        $money = $this->data['apply_money']; // 申请的金额
        $practical_money = $this->data['practical_money']; // 最终金额
        if ($practical_money <= 0)
            return app('json')->json_error('提现金额必须大于0');
        $user = Db::name('user')->field('support_money,status,is_auth')->where('id', $this->userId)->find();
        if ($user['status'] != 1)
            return app('json')->json_error('账号已被禁用');
        if ($user['is_auth'] != 1)
            return app('json')->json_error('你还未实名认证');
        if ($money <= 0)
            return app('json')->json_error('提现金额要大于0');
        $pay_configs = get_config(2); // 获取支付设置
        try {
            /** @var AliPay $pay */
            $pay = app()->make(AliPay::class, ['withdrawal']);
            $rpm = $pay->withdrawal($this->data);
            if ($rpm['flag']) {
                Db::name('withdrawal_log')->where('id', $this->data['id'])->update(['status' => 1, 'out_biz_no' => $rpm['data']['out_biz_no'], 'update_at' => date('Y-m-d H:i:s', time()), 'final_transfer_type' => $pay_configs['TRANSFERSTATUS']]);
                return app('json')->json_success('提现成功');
            } else {
                Db::name('withdrawal_log')->where('id', $this->data['id'])->update(['fail_log' => $rpm['msg'], 'status' => 2]);
                return app('json')->json_error('提现失败');
            }
        } catch (\Exception $e) {
            return app('json')->json_error('提现失败');
        }
    }

    /**
     * 后台易泰扶持提现
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function adminYitaiSupportWithdrawal()
    {

        $money = $this->data['apply_money']; // 申请的金额
        $practical_money = $this->data['practical_money']; // 最终金额
        if ($practical_money <= 0)
            return app('json')->json_error('提现金额必须大于0');
        $user = Db::name('user')->field('trade_support_money,status,is_auth')->where('id', $this->userId)->find();
        if ($user['status'] != 1)
            return app('json')->json_error('账号已被禁用');
        if ($user['is_auth'] != 1)
            return app('json')->json_error('你还未实名认证');
        if ($money <= 0)
            return app('json')->json_error('提现金额要大于0');
        $pay_configs = get_config(2); // 获取支付设置
        try {
            /** @var AliPay $pay */
            $pay = app()->make(AliPay::class, ['withdrawal']);
            $rpm = $pay->withdrawal($this->data);
            if ($rpm['flag']) {
                Db::name('withdrawal_log')->where('id', $this->data['id'])->update(['status' => 1, 'out_biz_no' => $rpm['data']['out_biz_no'], 'update_at' => date('Y-m-d H:i:s', time()), 'final_transfer_type' => $pay_configs['TRANSFERSTATUS']]);
                return app('json')->json_success('提现成功');
            } else {
                Db::name('withdrawal_log')->where('id', $this->data['id'])->update(['fail_log' => $rpm['msg'], 'status' => 2]);
                return app('json')->json_error('提现失败');
            }
        } catch (\Exception $e) {
            return app('json')->json_error('提现失败');
        }
    }

    /**
     * 魔术方法
     * @param $name
     * @param $arguments
     * @return $this
     */
    public function __call($name, $arguments)
    {
        // TODO: Implement __call() method.
        if ($name == 'data') {
            $this->{$name} = $arguments[0];
        } else {
            $this->{$name} = $arguments[0];
        }
        return $this;
    }
}